ROOT_DIR=$(pwd)/..
SCRIPT_DIR=$ROOT_DIR/RNOH_Script
OUTPUT_DIR=$SCRIPT_DIR/outputs
RNOH=react-native-harmony
RNOH_DIR=$ROOT_DIR/$RNOH
RNOH_CLI=react-native-harmony-cli
RNOH_CLI_DIR=$ROOT_DIR/$RNOH_CLI
RNOH_SAMPLE=react-native-harmony-sample-package
RNOH_SAMPLE_DIR=$ROOT_DIR/$RNOH_SAMPLE
TESTER_DIR=$ROOT_DIR/tester
HARMONY_DIR=$TESTER_DIR/harmony
RNOH_HARMONY=react_native_openharmony
RNOH_SAMPLE_PACKAGE=sample_package
RNOH_HARMONY_DIR=$HARMONY_DIR/$RNOH_HARMONY
RNOH_SAMPLE_PACKAGE_DIR=$HARMONY_DIR/$RNOH_SAMPLE_PACKAGE
VERSION=$(cat version.txt)

# 删除文件
function remove() {
    if [ -e $1 ]
        then
        rm -rf $1
        echo "[INFO] File $1 is removed"
    else 
        echo "[WARNNIG] File $1 is not exist"
    fi
}

# 执行命令
function executeCommands() {
    local commands=("$@")  # 将所有传入的参数作为命令存储在一个数组中
    local errorMessage=${commands[-1]}  # 最后一个参数作为错误信息
    unset commands[-1]  # 移除最后一个参数（错误信息），只保留命令

    for command in "${commands[@]}"; do
        $command
        if [ $? -ne 0 ]; then
            echo "[ERROR] $errorMessage"
            echo "[INFO] Check $LOG_FILE for more details"
            exit 1
        fi
    done
}

# 生成tgz包
function generateTgz() {
    echo "[INFO] Start to generate $1 tgz package $2"
    executeCommands "cd $2" "remove $2/node_modules" "remove $2/package-lock.json" "remove $2/*.tgz" "Failed to generate $1 tgz package $2"
    # 开始安装依赖
    echo "[INFO] Start to install $1 dependencies"
    executeCommands "npm install" "Failed to install $1 dependencies"
    # 开始打包
    echo "[INFO] Start to pack $1"
    executeCommands "npm pack" "Failed to pack $1"
    # 拷贝tgz包到outputs目录
    echo "[INFO] Start to copy $1 tgz package to outputs"
    executeCommands "cp *.tgz $OUTPUT_DIR/" "Failed to copy $1 tgz package to outputs"

    echo "[SUCCESS] $1 tgz package is generated"
}

# 构建Tester前端工程
function installTester() {
    # 安装tester依赖
    echo "[INFO] Start to install Tester dependencies"
    executeCommands "cd $TESTER_DIR" "remove $TESTER_DIR/node_modules" "remove $TESTER_DIR/package-lock.json" "npm install" "Failed to install Tester dependencies"
    # 构建bundle
    echo "[INFO] Start to build Tester"
    executeCommands "npm run dev" "Failed to build Tester"

    echo "[SUCCESS] Tester is built"
}

# JS工程构建
function buildJavaScript() {
    # 生成rnoh-cli tgz包
    generateTgz $RNOH_CLI $RNOH_CLI_DIR
    # 生成rnoh-sample tgz包
    generateTgz $RNOH_SAMPLE $RNOH_SAMPLE_DIR
    # 生成rnoh tgz包
    generateTgz $RNOH $RNOH_DIR
    # 安装tester前端工程
    installTester
}

# 清理RNOH包
CLEAN_COUNT=0
function clean() {
    if [ $CLEAN_COUNT -eq 0 ]; then
        echo "[INFO] hvigorw clean"
        executeCommands "cd $HARMONY_DIR" "hvigorw clean" "Failed to clean RNOH package"
        executeCommands "remove $RNOH_HARMONY_DIR/.cxx" "Failed to remove $RNOH_HARMONY_DIR/.cxx"
        executeCommands "remove $HARMONY_DIR/entry/.cxx" "Failed to remove $HARMONY_DIR/entry/.cxx"
        executeCommands "remove $RNOH_SAMPLE_PACKAGE_DIR/.cxx" "Failed to remove $RNOH_SAMPLE_PACKAGE_DIR/.cxx"
        echo "[SUCCESS] Successfully cleaned"
        CLEAN_COUNT=1
    else
        if [ "$1" == $RNOH_HARMONY_DIR ]; then
            echo "[INFO] hvigorw clean"
            executeCommands "cd $HARMONY_DIR" "hvigorw clean" "Failed to clean RNOH package"
            executeCommands "remove $RNOH_HARMONY_DIR/.cxx" "Failed to remove $RNOH_HARMONY_DIR/.cxx"
            echo "[SUCCESS] Successfully cleaned"
        fi
    fi
}

# 安装原生依赖
INSTALL_COUNT=0
function ohpmInstall() {
    if [ $INSTALL_COUNT -eq 0 ]; then
        echo "[INFO] Start to ohpm install"
        executeCommands "cd $HARMONY_DIR" "ohpm install" "Failed to ohpm install"
        INSTALL_COUNT=1
    else
        echo "[INFO] ohpm install has already been executed, skipping..."
    fi
}

# 生成归档包名称
function generateArchiveName() {
    HAR_NAME=$RNOH_HARMONY
    # 判断是否是jsvm分支
    local branch_name=$(cd $ROOT_DIR && git symbolic-ref --short HEAD)
    if echo $branch_name | grep -q "jsvm"; then
        HAR_NAME=${HAR_NAME}_jsvm
    fi
    echo $HAR_NAME
} 

# 生成debug包
function buildDebug() {
    # 清包
    clean $RNOH_HARMONY_DIR
    # 构建前准备环境
    ohpmInstall
    # 打包
    echo "[INFO] Start to build debug har package"
    executeCommands "cd $HARMONY_DIR" "hvigorw assembleHar --mode module -p module=$RNOH_HARMONY@default -p product=default -p buildMode=debug -p debuggable=true --no-daemon" "Failed to build debug har package"
    # 归档
    executeCommands "cp $RNOH_HARMONY_DIR/build/default/outputs/default/$RNOH_HARMONY.har $OUTPUT_DIR/$(generateArchiveName)-$VERSION.har" "Failed to copy debug har package to outputs"
    echo "[SUCCESS] Successfully built debug har package"
}

# 生成release包
function buildRelease() {
    echo "[INFO] Start to build release har package"
    # 清包
    clean $RNOH_HARMONY_DIR
    # 构建前准备环境
    echo "[INFO] Start to prepare release environment"
    executeCommands "cd $SCRIPT_DIR" "node generateHeader.js" "Failed to prepare release environment"
    ohpmInstall
    # 打包
    echo "[INFO] Start to build release har package"
    executeCommands "cd $HARMONY_DIR" "hvigorw assembleHar --mode module -p module=$RNOH_HARMONY@default -p product=default -p buildMode=release -p debuggable=false --no-daemon" "Failed to build release har package"
    # 归档
    executeCommands "cp $RNOH_HARMONY_DIR/build/default/outputs/default/$RNOH_HARMONY.har $OUTPUT_DIR/$(generateArchiveName)_release-$VERSION.har" "Failed to copy release har package to outputs"
    echo "[SUCCESS] Successfully built release har package"
    # 还原环境
    echo "[INFO] Start to restore release environment"
    executeCommands "cp $SCRIPT_DIR/bak/CMakeLists.txt.bak $RNOH_HARMONY_DIR/src/main/cpp/CMakeLists.txt" "cp $SCRIPT_DIR/bak/build-profile.json5.bak $RNOH_HARMONY_DIR/build-profile.json5" "remove $RNOH_HARMONY_DIR/src/main/include" "Failed to restore release environment"
    echo "[SUCCESS] Successfully restored release environment"
}

# 生成sample包
function buildSample() {
    # 构建前准备环境
    ohpmInstall
    # 打包
    echo "[INFO] Start to build sample package"
    executeCommands "cd $HARMONY_DIR" "hvigorw assembleHar --mode module -p module=$RNOH_SAMPLE_PACKAGE@default -p product=default -p buildMode=debug -p debuggable=true --no-daemon" "Failed to build sample package"
    # 归档
    executeCommands "cp $RNOH_SAMPLE_PACKAGE_DIR/build/default/outputs/default/$RNOH_SAMPLE_PACKAGE.har $OUTPUT_DIR/${RNOH_SAMPLE_PACKAGE}-$VERSION.har" "Failed to copy sample package to outputs"
    echo "[SUCCESS] Successfully built sample package"
}

# 生成tester包
function buildTester() {
    # 清包
    clean
    # ohpm装依赖
    ohpmInstall
    # 生成hap包
    echo "[INFO] Start to build RN_Tester"
    executeCommands "cd $HARMONY_DIR" "hvigorw --mode module -p module=entry@default -p product=default -p buildMode=debug -p requiredDeviceType=phone assembleHap --analyze=normal --parallel --incremental --no-daemon" "Failed to build RN_Tester"
    # 归档
    executeCommands "cp $HARMONY_DIR/entry/build/default/outputs/default/entry-default-signed.hap $OUTPUT_DIR/RN_Tester-$VERSION.hap" "Failed to copy RN_Tester to outputs"
    echo "[SUCCESS] Successfully built RN_Tester"
}

# 清空outputs文件夹
function clearOutputs() {
    executeCommands "cd $SCRIPT_DIR" "remove $OUTPUT_DIR" "Failed to clear outputs"
    echo "[SUCCESS] Outputs is cleared"
}

# 构建
function build() {
    tgz="tgz"
    sample="sample"
    debug="debug"
    release="release"
    tester="tester"
    clearOutputs="clear"
    if [ "$1" == "$tgz" ]
        then
        buildJavaScript
    elif [ "$1" == "$sample" ]
        then
        buildSample
    elif [ "$1" == "$debug" ]
        then
        buildDebug  
    elif [ "$1" == "$release" ]
        then
        buildRelease
    elif [ "$1" == "$tester" ]
        then
        buildTester
    elif [ "$1" == "$clearOutputs" ]
        then
        clearOutputs
    else
        echo "[ERROR] build type $1 is not support"
    fi
}

# 生成日志记录
mkdir -p $OUTPUT_DIR
mkdir -p $OUTPUT_DIR/log
LOG_FILE=$OUTPUT_DIR/log/build-$(date +"%Y%m%d%H%M%S").log
truncate -s 0 $LOG_FILE
exec > >(tee -a $LOG_FILE) 2> >(tee -a $LOG_FILE >&2)

argList="tgz sample debug release"
if [ "$#" -ge 1 ]
    then
    argList=$@
fi

for arg in $argList; do
    build $arg
done